package com.wstuo.common.config.onlinelog.service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.wstuo.common.config.backup.dto.BackupFileDTO;
import com.wstuo.common.config.onlinelog.dao.IUserErrLogDAO;
import com.wstuo.common.config.onlinelog.dto.UserErrLogDTO;
import com.wstuo.common.config.onlinelog.entity.UserErrLog;
import com.wstuo.common.config.util.CompratorByLastModified;
import com.wstuo.common.dto.PageDTO;
import com.wstuo.common.file.csv.CSVWriter;
import com.wstuo.common.security.utils.LanguageContent;
import com.wstuo.common.util.TimeUtils;

/**
 * 用户操作异常Service
 * 
 * @author WSTUO
 * 
 */
public class UserErrLogService implements IUserErrLogService {
	private static final Logger LOGGER = Logger.getLogger(UserErrLogService.class);
	@Autowired
	private IUserErrLogDAO userErrLogDAO;

	/**
	 * 分页查看用户操作异常记录
	 * 
	 * @param userErrLogDTO
	 * @param start
	 * @param limit
	 * @return PageDTO
	 */
	@Transactional
	public PageDTO findUserErrLogPager(final UserErrLogDTO userErrLogDTO, int start, int limit, String sidx, String sord) {
		PageDTO p = userErrLogDAO.findUserErrLogPager(userErrLogDTO, start, limit, sidx, sord);
		List<UserErrLog> entities = p.getData();
		List<UserErrLogDTO> dtos = new ArrayList<UserErrLogDTO>();
		for (UserErrLog req : entities) {
			UserErrLogDTO dto = new UserErrLogDTO();
			entity2dto(req, dto);
			dtos.add(dto);
		}
		p.setData(dtos);
		return p;
	}

	/**
	 * entity to DTO
	 * 
	 * @param entity
	 * @param userErrLogDTO
	 */
	private void entity2dto(UserErrLog entity, UserErrLogDTO userErrLogDTO) {
		userErrLogDTO.setErrCause(entity.getErrCause());
		userErrLogDTO.setErrMsg(entity.getErrMsg());
		userErrLogDTO.setId(entity.getId());
		userErrLogDTO.setMethodName(entity.getMethodName());
		userErrLogDTO.setResourceId(entity.getResourceId());
		userErrLogDTO.setResourceName(entity.getResourceName());
		userErrLogDTO.setTime(entity.getTime());
		userErrLogDTO.setUserName(entity.getUserName());
	}

	/**
	 * DTO to entity
	 * 
	 * @param userErrLogDTO
	 * @param entity
	 */
	private void dto2entity(UserErrLogDTO userErrLogDTO, UserErrLog entity) {
		entity.setErrCause(userErrLogDTO.getErrCause());
		entity.setErrMsg(userErrLogDTO.getErrMsg());
		entity.setId(userErrLogDTO.getId());
		entity.setMethodName(userErrLogDTO.getMethodName());
		entity.setResourceId(userErrLogDTO.getResourceId());
		entity.setResourceName(userErrLogDTO.getResourceName());
		entity.setTime(userErrLogDTO.getTime());
		entity.setUserName(userErrLogDTO.getUserName());
	}

	/**
	 * 保存用户操作异常记录
	 * 
	 * @param userErrLogDTO
	 */
	@Transactional
	public void saveUserErrLog(UserErrLogDTO userErrLogDTO) {
		UserErrLog userErrLog = new UserErrLog();
		dto2entity(userErrLogDTO, userErrLog);
		userErrLogDAO.merge(userErrLog);
		userErrLogDTO.setId(userErrLog.getId());
	}

	/**
	 * 导出数据方法
	 */
	@Transactional
	public void exportUserErrLog(UserErrLogDTO userErrLogDTO, int start, int limit, String fileName) {
		StringWriter sw = new StringWriter();
		CSVWriter csvw = new CSVWriter(sw);

		List<String[]> data = new ArrayList<String[]>();
		LanguageContent lc = LanguageContent.getInstance();
		data.add(new String[] { lc.getContent("common.id"), lc.getContent("common.Username"), lc.getContent("common.createTime"), lc.getContent("lable.MethodName"), lc.getContent("lable.ResourceName"),// lc.getContent("lable.ResourceId"),
				lc.getContent("lable.ErrCause"), lc.getContent("lable.ErrMsg") });
		limit = csvw.EXPORT_SIZE;
		PageDTO p = userErrLogDAO.findUserErrLogPager(userErrLogDTO, start, limit, null, null);
		if (p != null && p.getData() != null && p.getData().size() > 0) {
			List<UserErrLog> entities = p.getData();
			for (UserErrLog userErrLog : entities) {
				data.add(new String[] { userErrLog.getId().toString(), userErrLog.getUserName(), TimeUtils.format(userErrLog.getTime(),TimeUtils.DATETIME_PATTERN), userErrLog.getMethodName(), userErrLog.getResourceName(),
						// resourceId,
						userErrLog.getErrCause(), userErrLog.getErrMsg() });
			}
		}
		csvw.writeAll(data);
		
		byte[] bs = null;
		try {
			bs = sw.getBuffer().toString().getBytes("GBK");
		} catch (UnsupportedEncodingException e1) {
			LOGGER.error(e1);
		}
		OutputStream stream1 = null;
		try {
			stream1 = new FileOutputStream(fileName);
			if(stream1!=null){
				stream1.write(bs);
			}
		} catch (IOException e) {
			LOGGER.error("export User ErrLog", e);
		} catch (Exception e) {
			LOGGER.error("export User ErrLog", e);
		} finally {
			try {
				if (stream1 != null) {
					stream1.close();
				}
				if (csvw != null) {
					csvw.flush();
					csvw.close();
				}
				if (sw != null) {
					sw.flush();
					sw.close();
				}
			} catch (IOException e) {
				LOGGER.error(e);
			}
		}
	}

	/**
	 * 查询错误日志列表
	 * @param page
	 * @param rows
	 * @param path
	 * @param csvFileName
	 * @param startTime
	 * @param endTime
	 * @return PageDTO
	 */
	@Transactional
	public PageDTO showAllErrLogFiles(int page, int rows, String path, String csvFileName, String startTime, String endTime) {
		PageDTO pageDTO = new PageDTO();
		DecimalFormat df = new DecimalFormat("#0.000");// 数字格式化
		List<BackupFileDTO> fileList = new ArrayList<BackupFileDTO>();
		File file = new File(path);// 读取目录
		if (!file.exists()) {// 创建目录结构
			file.mkdirs();
		}
		int start = (page - 1) * rows;
/*		if (page != 1)
			start += 1;*/
		int row = rows;
		
		File files[] = file.listFiles();
		if (files != null) {
			Arrays.sort(files, new CompratorByLastModified());
			int toolsize = files.length;
			for (int i = start; i < toolsize; i++) {
				if (files[i].isFile()) {
					String fileName = files[i].getName();
					if (fileName.indexOf(".csv") != -1) {
						String fileType = fileName.substring(fileName.lastIndexOf(".csv"), fileName.length());
						// 只读取csv文件
						if (".csv".equals(fileType) 
								&& searchDecide(TimeUtils.format(new Date(files[i].lastModified()),TimeUtils.DATETIME_PATTERN), fileName,csvFileName,startTime,endTime)
								&& row-- != 0) {// 搜索判断
							BackupFileDTO dto = new BackupFileDTO();
							dto.setFileName(fileName);// 日志名称
							dto.setCrateDate(TimeUtils.format(new Date(files[i].lastModified()),TimeUtils.DATETIME_PATTERN));// 创建时间
							dto.setFileSize(df.format(files[i].length() / 1048576.0000) + "MB");// 大小
							fileList.add(dto);
						}else{
							toolsize--;
						}
					}else{
						toolsize--;
					}
				}else{
					toolsize--;
				}
			}
			if (fileList.size() > 0) {
				pageDTO.setData(fileList);
				pageDTO.setPage(page);
				int n = (toolsize % rows == 0) ? 0 : 1 + toolsize / rows;
				pageDTO.setTotal(n);
				pageDTO.setTotalSize(toolsize);
				pageDTO.setRows(rows);
			}
		}
		
		return pageDTO;
	}

	/**
	 * 搜索判断
	 * 
	 * @param date
	 *            备份日期
	 * @param filename
	 *            文件名
	 * @return boolean
	 */
	private boolean searchDecide(String date, String fileName, String csvFileName, String startTime, String endTime) {
		boolean bool = true;
		if (csvFileName != null && csvFileName.length() > 0 && !fileName.contains(csvFileName)) {
			bool = false;
		}
		Date d = TimeUtils.parse(date,TimeUtils.DATETIME_PATTERN);
		if (startTime != null && startTime.length() > 0) {
			Date start = TimeUtils.parse(startTime,TimeUtils.DATETIME_PATTERN);
			if (d.before(start)) // 说明date 比 start 早
				bool = false;
		}
		if (endTime != null && endTime.length() > 0) {
			Date end = TimeUtils.parse(endTime,TimeUtils.DATETIME_PATTERN);
			if (d.after(end))
				bool = false;
		}
		return bool;
	}
	
	/**
	 * 删除错误日志
	 * @param fileNames
	 * @param path
	 */
	@Transactional
	public void deleteErrorLog(String[] fileNames,String path){
		if(fileNames!=null && fileNames.length>0){
			for(String fileName:fileNames){
				File f=new File(path+"/"+fileName);
				if(f.exists()){
					f.delete();
				}
			}
		}
	}
}
